<template>
  <div class="kanban-container">
    <el-skeleton v-if="loading" animated :rows="6" />
    <el-empty v-else-if="!tasks.length" description="暂无任务数据" />
    <el-scrollbar v-else class="kanban-scroll">
      <div class="kanban-board">
        <div
          v-for="column in columns"
          :key="column.key"
          class="kanban-column"
          :data-status="column.key"
        >
        <header class="column-header">
          <div class="column-title">
            <span class="dot" :style="{ background: column.color }" />
            <strong>{{ column.title }}</strong>
          </div>
          <div class="column-header-right">
            <span class="column-count">{{ column.items.length }}</span>
            <el-tooltip content="新建任务" placement="top">
              <el-button
                type="primary"
                circle
                plain
                size="small"
                class="create-button"
                @click.stop="handleCreateTask(column.key)"
              >
                <el-icon><Plus /></el-icon>
              </el-button>
            </el-tooltip>
          </div>
        </header>

        <el-scrollbar class="column-scroll">
          <Draggable
            :list="column.items"
            item-key="id"
            class="column-scroll-list"
            :component-data="{ attrs: { 'data-status': column.key } }"
            group="task-status"
            :animation="180"
            :disabled="loading"
            @start="handleDragStart"
            @end="(event: any) => handleDragEnd(event)"
          >
            <template #item="{ element }">
              <el-card
                :data-task-id="element.id"
                :data-id="element.id"
                shadow="never"
                class="kanban-card"
                @click="$emit('open-detail', element.id)"
              >
                <div class="card-header">
                  <div class="card-id-wrapper">
                    <span class="card-id">#{{ element.id.slice(-8) }}</span>
                  </div>
                  <el-tag size="small" :type="priorityTagType(element.priority)" class="priority-tag">
                    {{ getPriorityLabel(element.priority) }}
                  </el-tag>
                </div>
                <div class="card-title" :title="element.title">{{ element.title }}</div>
                <div class="card-meta">
                  <div class="meta-item" v-if="element.assignee_id">
                    <UserDisplay
                      :user-id="element.assignee_id"
                      :user-name="element.assignee_name"
                      :users-map="props.usersMap"
                      :show-avatar="true"
                      size="small"
                    />
                  </div>
                  <div class="meta-item" v-else>
                    <el-icon class="meta-icon"><UserFilled /></el-icon>
                    <span class="meta-text text-muted">未分配</span>
                  </div>
                  <div class="meta-item" v-if="element.project_name">
                    <el-icon class="meta-icon"><Folder /></el-icon>
                    <span class="meta-text">{{ element.project_name }}</span>
                  </div>
                </div>
                <div class="card-footer">
                  <span class="time">
                    <el-icon class="time-icon"><Clock /></el-icon>
                    {{ formatDate(element.updated_at) }}
                  </span>
                  <el-button 
                    type="primary" 
                    text 
                    size="small" 
                    class="edit-button"
                    @click.stop="$emit('open-edit', element.id)"
                  >
                    <el-icon><Edit /></el-icon>
                  </el-button>
                </div>
              </el-card>
            </template>
          </Draggable>
        </el-scrollbar>
        </div>
      </div>
    </el-scrollbar>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, UserFilled, Folder, Clock, Edit } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
import Draggable from 'vuedraggable'
import type { Task } from '@/types/task'
import UserDisplay from '@/components/ui/UserDisplay.vue'

const props = defineProps<{
  tasks: Task[]
  statusOptions: Array<{ value: string; label: string; color?: string }>
  priorityOptions: Array<{ value: string; label: string }>
  loading: boolean
  usersMap?: Map<string, any> | Record<string, any> | null
}>()

const emit = defineEmits<{
  (event: 'open-detail', id: string): void
  (event: 'open-edit', id: string): void
  (event: 'update-status', payload: { id: string; status: string }): void
  (event: 'create-task', status: string): void
}>()

const recycleColumn = {
  key: 'unclassified',
  title: '未分类',
  color: '#c9ccd8'
}

const getPriorityLabel = (value?: string | null) => {
  if (!value) return '未设置'
  return props.priorityOptions.find(option => option.value === value)?.label ?? value
}

const priorityTagType = (priority?: string | null) => {
  const code = priority?.toLowerCase()
  switch (code) {
    case 'critical':
    case 'urgent':
      return 'danger'
    case 'high':
      return 'warning'
    case 'medium':
      return 'success'
    default:
      return 'info'
  }
}

const formatDate = (value?: string) => {
  if (!value) return '—'
  return dayjs(value).format('MM-DD HH:mm')
}

const columns = computed(() => {
  const map = new Map<string, Task[]>()
  props.statusOptions.forEach(option => map.set(option.value, []))

  const fallback: Task[] = []

  props.tasks.forEach(item => {
    if (item.status && map.has(item.status)) {
      map.get(item.status)?.push(item)
    } else {
      fallback.push(item)
    }
  })

  const result = props.statusOptions.map(option => ({
    key: option.value,
    title: option.label,
    color: option.color || '#528bff',
    items: map.get(option.value) || []
  }))

  if (fallback.length) {
    result.push({
      ...recycleColumn,
      items: fallback
    })
  }

  return result
})

const handleCreateTask = (status: string) => {
  emit('create-task', status)
}

const handleDragStart = () => {
  document.body.classList.add('dragging')
}

const handleDragEnd = async (event: any) => {
  document.body.classList.remove('dragging')
  
  const { item, from, to, oldIndex, newIndex } = event || {}
  
  if (!item || !from || !to) {
    return
  }
  
  const targetColumn = to.closest?.('.kanban-column') || to.parentElement?.closest?.('.kanban-column')
  const finalTargetStatus = targetColumn?.getAttribute('data-status') || 
    targetColumn?.dataset?.status ||
    to?.getAttribute('data-status') ||
    to?.dataset?.status
  
  const sourceColumn = from.closest?.('.kanban-column') || from.parentElement?.closest?.('.kanban-column')
  const sourceStatus = sourceColumn?.getAttribute('data-status') || 
    sourceColumn?.dataset?.status ||
    from?.getAttribute('data-status') ||
    from?.dataset?.status
  
  if (finalTargetStatus === sourceStatus) {
    return
  }
  
  if (!finalTargetStatus) {
    console.warn('无法获取目标状态', { targetColumn, to, event })
    if (oldIndex !== undefined && from) {
      const children = from.children
      if (children[oldIndex]) {
        from.insertBefore(item, children[oldIndex])
      } else if (oldIndex === 0) {
        from.insertBefore(item, children[0])
      } else {
        from.appendChild(item)
      }
    }
    return
  }
  
  let taskId = item.getAttribute?.('data-task-id') ||
    item.dataset?.taskId ||
    item.getAttribute?.('data-id') ||
    item.dataset?.id
  
  if (!taskId) {
    const cardElement = item.querySelector?.('.kanban-card')
    if (cardElement) {
      taskId = cardElement.getAttribute('data-task-id') ||
        cardElement.getAttribute('data-id') ||
        cardElement.dataset?.taskId ||
        cardElement.dataset?.id
    }
  }
  
  if (!taskId && event?.itemContext) {
    taskId = event.itemContext.element?.id
  }
  
  if (!taskId && item.__draggable_context) {
    taskId = item.__draggable_context.element?.id
  }
  
  if (!taskId && typeof newIndex === 'number' && newIndex >= 0) {
    const targetColumnData = columns.value.find(col => col.key === finalTargetStatus)
    if (targetColumnData && targetColumnData.items[newIndex]) {
      taskId = targetColumnData.items[newIndex].id
    }
  }
  
  if (!taskId) {
    console.warn('拖拽事件缺少任务ID:', { item, from, to, oldIndex, newIndex, event })
    if (oldIndex !== undefined && from) {
      const children = from.children
      if (children[oldIndex]) {
        from.insertBefore(item, children[oldIndex])
      } else if (oldIndex === 0) {
        from.insertBefore(item, children[0])
      } else {
        from.appendChild(item)
      }
    }
    ElMessage.error('无法获取任务信息，请重试')
    return
  }

  emit('update-status', { id: taskId, status: finalTargetStatus })
}
</script>

<style scoped>
.kanban-container {
  min-height: 0;
  min-width: 0;
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.kanban-scroll {
  flex: 1;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  height: 100%;
}

.kanban-scroll :deep(.el-scrollbar) {
  height: 100%;
}

.kanban-scroll :deep(.el-scrollbar__wrap) {
  overflow-y: hidden;
  overflow-x: auto;
  height: 100%;
}

.kanban-board {
  display: flex;
  gap: 16px;
  padding-bottom: 4px;
  min-height: 100%;
  width: max-content;
}

.kanban-column {
  display: flex;
  flex-direction: column;
  flex: 0 0 280px;
  height: calc(100vh - 280px);
  min-height: 400px;
  max-height: calc(100vh - 200px);
  border-radius: 16px;
  background: linear-gradient(180deg, #ffffff 0%, #f4f7ff 100%);
  box-shadow: inset 0 0 0 1px rgba(91, 118, 184, 0.12);
  overflow: hidden;
}

.column-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(102, 126, 185, 0.12);
}

.column-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: #264074;
}

.column-title .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.column-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.column-count {
  font-size: 12px;
  color: #7582a4;
}

.create-button {
  flex-shrink: 0;
}

.column-scroll {
  flex: 1;
  padding: 12px 12px 6px;
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

.column-scroll :deep(.el-scrollbar) {
  height: 100%;
}

.column-scroll :deep(.el-scrollbar__wrap) {
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto !important;
}

.column-scroll :deep(.el-scrollbar__view) {
  min-height: auto;
}

.column-scroll :deep(.el-scrollbar__bar) {
  right: 2px;
}

.column-scroll :deep(.el-scrollbar__bar.is-vertical) {
  width: 6px;
}

.column-scroll :deep(.el-scrollbar__thumb) {
  background-color: rgba(144, 147, 153, 0.3);
  border-radius: 3px;
}

.column-scroll :deep(.el-scrollbar__thumb:hover) {
  background-color: rgba(144, 147, 153, 0.5);
}

.column-scroll-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: auto;
}

.kanban-card {
  margin-bottom: 12px;
  border-radius: 12px;
  cursor: pointer;
  border: 1px solid #e4e7ed;
  background: #ffffff;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  position: relative;
  overflow: hidden;
}

.kanban-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background: linear-gradient(180deg, #409eff 0%, #66b1ff 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.kanban-card:hover {
  transform: translateY(-4px);
  border-color: #409eff;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
}

.kanban-card:hover::before {
  opacity: 1;
}

.kanban-card:active {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.kanban-card :deep(.el-card__body) {
  padding: 14px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 10px;
  gap: 8px;
}

.card-id-wrapper {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.card-id {
  font-size: 11px;
  color: #909399;
  font-weight: 500;
  font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
  letter-spacing: 0.5px;
}

.priority-tag {
  flex-shrink: 0;
  font-size: 11px;
  padding: 0 8px;
  height: 20px;
  line-height: 20px;
  font-weight: 500;
}

.card-title {
  font-weight: 600;
  font-size: 14px;
  color: #303133;
  margin-bottom: 12px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
  min-height: 42px;
  transition: color 0.2s ease;
}

.kanban-card:hover .card-title {
  color: #409eff;
}

.card-meta {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
  padding-top: 8px;
  border-top: 1px solid #f0f2f5;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #606266;
}

.meta-icon {
  font-size: 14px;
  color: #909399;
  flex-shrink: 0;
}

.meta-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.meta-text.text-muted {
  color: #c0c4cc;
}

.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 10px;
  border-top: 1px solid #f0f2f5;
}

.time {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #909399;
}

.time-icon {
  font-size: 12px;
}

.edit-button {
  padding: 4px 8px;
  opacity: 0.7;
  transition: all 0.2s ease;
}

.kanban-card:hover .edit-button {
  opacity: 1;
  color: #409eff;
}

.edit-button:hover {
  opacity: 1;
  color: #409eff;
  background-color: #ecf5ff;
}
</style>

